View Javadoc

1   // TimeZone.java, created Thu Jul  4  4:50:04 2002 by joewhaley
2   // Copyright (C) 2001-3 John Whaley <jwhaley@alum.mit.edu>
3   // Licensed under the terms of the GNU LGPL; see COPYING for details.
4   package joeq.ClassLib.Common.java.util;
5   
6   import joeq.Bootstrap.MethodInvocation;
7   import joeq.Class.jq_Class;
8   import joeq.Class.jq_DontAlign;
9   import joeq.Class.jq_Method;
10  import joeq.Class.jq_NameAndDesc;
11  import joeq.Main.jq;
12  import joeq.Memory.CodeAddress;
13  import joeq.Memory.HeapAddress;
14  import joeq.Runtime.Debug;
15  import joeq.Runtime.Reflection;
16  import joeq.Runtime.SystemInterface;
17  import joeq.Runtime.Unsafe;
18  import joeq.Runtime.SystemInterface.ExternalLink;
19  import joeq.Runtime.SystemInterface.Library;
20  import jwutil.util.Assert;
21  
22  /***
23   * TimeZone
24   *
25   * @author  John Whaley <jwhaley@alum.mit.edu>
26   * @version $Id: TimeZone.java 1941 2004-09-30 03:37:06Z joewhaley $
27   */
28  abstract class TimeZone {
29  
30      public static TimeZoneInformation cachedTimeZone;
31      public static int cachedTimeZoneId;
32  
33      private static String getSystemTimeZoneID(String javaHome, String region) {
34          if (cachedTimeZone == null) {
35              TimeZoneInformation info = new TimeZoneInformation();
36              int rc = get_time_zone_information(info);
37              if (rc == TIME_ZONE_ID_INVALID) return null;
38              cachedTimeZone = info;
39              cachedTimeZoneId = rc;
40          }
41          String s;
42          switch (cachedTimeZoneId) {
43              case TIME_ZONE_ID_UNKNOWN:
44              case TIME_ZONE_ID_STANDARD:
45                  s = cachedTimeZone.getStandardName();
46                  break;
47              case TIME_ZONE_ID_DAYLIGHT:
48                  s = cachedTimeZone.getDaylightName();
49                  break;
50              default:
51                  return null;
52          }
53          if (s.equals("Pacific Standard Time") || s.equals("Pacific Daylight Time"))
54              return "America/Los Angeles";
55          // TODO: other time zones.
56          return "America/Los Angeles";
57      }
58      
59      private static String getSystemGMTOffsetID() {
60          if (cachedTimeZone == null) {
61              TimeZoneInformation info = new TimeZoneInformation();
62              int rc = get_time_zone_information(info);
63              if (rc == TIME_ZONE_ID_INVALID) return null;
64              cachedTimeZone = info;
65              cachedTimeZoneId = rc;
66          }
67          int bias = -cachedTimeZone.Bias;
68          int hr = bias / 60;
69          int min = java.lang.Math.abs(bias % 60);
70          String hr_s, min_s;
71          if (hr >= 0) {
72              if (hr <= 9) {
73                  hr_s = "+0"+hr;
74              } else {
75                  hr_s = "+"+hr;
76              }
77          } else {
78              hr = -hr;
79              min = -min;
80              if (hr <= 9) {
81                  hr_s = "-0"+hr;
82              } else {
83                  hr_s = "-"+hr;
84              }
85          }
86          Assert._assert(min >= 0);
87          if (min <= 9) {
88              min_s = ":0"+min;
89          } else {
90              min_s = ":"+min;
91          }
92          return "GMT"+hr_s+min_s;
93      }
94      
95      public static class TimeZoneInformation implements jq_DontAlign {
96          // from TIME_ZONE_INFORMATION structure in winbase.h
97          int Bias;
98          long StandardName0; // WCHAR array
99          long StandardName1;
100         long StandardName2;
101         long StandardName3;
102         short StandardDate_wYear;
103         short StandardDate_wMonth;
104         short StandardDate_wDayOfWeek;
105         short StandardDate_wDay;
106         short StandardDate_wHour;
107         short StandardDate_wMinute;
108         short StandardDate_wSecond;
109         short StandardDate_wMilliseconds;
110         int StandardBias;
111         long DaylightName0; // WCHAR array
112         long DaylightName1;
113         long DaylightName2;
114         long DaylightName3;
115         short DaylightDate_wYear;
116         short DaylightDate_wMonth;
117         short DaylightDate_wDayOfWeek;
118         short DaylightDate_wDay;
119         short DaylightDate_wHour;
120         short DaylightDate_wMinute;
121         short DaylightDate_wSecond;
122         short DaylightDate_wMilliseconds;
123         int DaylightBias;
124         
125         public void dump() {
126             Debug.writeln("Bias=", Bias);
127             Debug.write("StandardName=");
128             HeapAddress s = getStandardNameAddress();
129             try {
130                 Unsafe.pushArg(strlen(s));
131                 Unsafe.pushArgA(s);
132                 Unsafe.invoke(SystemInterface.debugwwriteln_8);
133             } catch (Throwable t) { }
134             Debug.write("StandardDate={ wYear=", StandardDate_wYear);
135             Debug.write(", wMonth=", StandardDate_wMonth);
136             Debug.write(", wDayOfWeek=", StandardDate_wDayOfWeek);
137             Debug.write(", wDay=", StandardDate_wDay);
138             Debug.write(", wHour=", StandardDate_wHour);
139             Debug.write(", wMinute=", StandardDate_wMinute);
140             Debug.write(", wSecond=", StandardDate_wSecond);
141             Debug.write(", wMilliseconds=", StandardDate_wMilliseconds);
142             Debug.writeln(" }");
143             Debug.writeln("StandardBias=", StandardBias);
144             
145             Debug.write("DaylightName=");
146             s = getDaylightNameAddress();
147             try {
148                 Unsafe.pushArg(strlen(s));
149                 Unsafe.pushArgA(s);
150                 Unsafe.invoke(SystemInterface.debugwwriteln_8);
151             } catch (Throwable t) { }
152             Debug.write("DaylightDate={ wYear=", DaylightDate_wYear);
153             Debug.write(", wMonth=", DaylightDate_wMonth);
154             Debug.write(", wDayOfWeek=", DaylightDate_wDayOfWeek);
155             Debug.write(", wDay=", DaylightDate_wDay);
156             Debug.write(", wHour=", DaylightDate_wHour);
157             Debug.write(", wMinute=", DaylightDate_wMinute);
158             Debug.write(", wSecond=", DaylightDate_wSecond);
159             Debug.write(", wMilliseconds=", DaylightDate_wMilliseconds);
160             Debug.writeln(" }");
161             Debug.writeln("DaylightBias=", Bias);
162         }
163         
164         public String getStandardName() {
165             HeapAddress s = getStandardNameAddress();
166             return fromCString(s);
167         }
168         
169         HeapAddress getStandardNameAddress() {
170             return (HeapAddress) HeapAddress.addressOf(this).offset(4);
171         }
172         
173         public String getDaylightName() {
174             HeapAddress s = getDaylightNameAddress();
175             return fromCString(s);
176         }
177         
178         HeapAddress getDaylightNameAddress() {
179             return (HeapAddress) HeapAddress.addressOf(this).offset(56);
180         }
181         
182         static String fromCString(HeapAddress s) {
183             StringBuffer sb = new StringBuffer();
184             int strlen = 0;
185             char c;
186             while ((c = (char)s.peek2()) != (char)0 && strlen < 32) {
187                 sb.append(c);
188                 ++strlen;
189                 s = (HeapAddress) s.offset(2);
190             }
191             return sb.toString();
192         }
193         
194         static int strlen(HeapAddress s) {
195             int strlen = 0;
196             while (s.peek2() != (short)0 && strlen < 32) {
197                 ++strlen;
198                 s = (HeapAddress) s.offset(2);
199             }
200             return strlen;
201         }
202         
203         
204     }
205     
206     public static int get_time_zone_information(TimeZoneInformation t) {
207         try {
208             CodeAddress a = GetTimeZoneInformation.resolve();
209             HeapAddress b = HeapAddress.addressOf(t);
210             Unsafe.pushArgA(b);
211             Unsafe.getThreadBlock().disableThreadSwitch();
212             int rc = (int) Unsafe.invoke(a);
213             Unsafe.getThreadBlock().enableThreadSwitch();
214             return rc;
215         } catch (Throwable x) { Assert.UNREACHABLE(); }
216         return 0;
217     }
218     
219     // defined in winbase.h
220     public static final int TIME_ZONE_ID_UNKNOWN = 0;
221     public static final int TIME_ZONE_ID_STANDARD = 1;
222     public static final int TIME_ZONE_ID_DAYLIGHT = 2;
223     public static final int TIME_ZONE_ID_INVALID = 0xFFFFFFFF;
224     
225     public static /*final*/ ExternalLink GetTimeZoneInformation;
226 
227     static {
228         if (jq.RunningNative) boot();
229         else if (jq.on_vm_startup != null) {
230             jq_Class c = (jq_Class) Reflection.getJQType(java.util.TimeZone.class);
231             jq_Method m = c.getDeclaredStaticMethod(new jq_NameAndDesc("boot", "()V"));
232             MethodInvocation mi = new MethodInvocation(m, null);
233             jq.on_vm_startup.add(mi);
234         }
235     }
236 
237     public static void boot() {
238         Library kernel32 = SystemInterface.registerLibrary("kernel32");
239 
240         if (kernel32 != null) {
241             GetTimeZoneInformation = kernel32.resolve("GetTimeZoneInformation");
242         } else {
243             GetTimeZoneInformation = null;
244         }
245 
246         //System.out.println("getSystemGMTOffsetID="+getSystemGMTOffsetID());
247         //cachedTimeZone.dump();
248         //System.out.println("timeZoneID="+cachedTimeZoneId);
249     }
250 }